﻿#region Namespace
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
using System.Threading;
using System.Diagnostics;
using System.Reflection;
using System.Net;
using System.IO;
using DCT.AutoUpdate.Code.Config;
using DCT.AutoUpdate.Code;
using System.Collections;
using DCT.AutoUpdate.Code.Log;
using System.Windows.Threading; 
#endregion

namespace DCT.AutoUpdate.App
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        private static ILog log = null;

        public static ILog Log {
            get {
                return log;
            }
        }

        public static void LogFlush() {
            var tmp = Log as FileLog;
            if (tmp != null) {
                tmp.Flush();
            }
        }

        private static Mutex m = null;

        public App()
        {
            if (log == null) {
                InitLog();
            }
            this.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
        }

        void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            Log.E("system"
                , "unhandle"
                , e.Exception);
        }

        protected override void OnStartup(StartupEventArgs e)
        {
            Log.I("system","app_start");
            //实现进程单例
            bool createnewone = false;
            Guid guid = Assembly.GetExecutingAssembly().ManifestModule.ModuleVersionId;
            m = new Mutex(true, guid.ToString(), out createnewone);

            if (!createnewone)
            {
                Log.I("system", "process_exist");
                this.Shutdown();
                return;
            }

            //获取xml
            string url = "http://localhost:3643/Update/latest.xml";
            IConfigParser cp = null;

            TimeoutController tc = new TimeoutController(delegate {
                WebRequest req = WebRequest.Create(url);
                req.Timeout = 60000;
                try
                {
                    using (WebResponse response = req.GetResponse())
                    {
                        using (var stream = response.GetResponseStream())
                        {
                            using (StreamReader reader = new StreamReader(stream))
                            {
                                string config = reader.ReadToEnd();
                                cp = new AutoUpdateXmlConfigParser();
                                cp.Load(config);
                                this.Properties["cp"] = cp;
                            }
                        }
                    }
                }
                catch (Exception ex) {
                    Log.E("system", "get_xml_error" + LogExtension.FormatDictory(
                        new Dictionary<string, string>() { { "url", url } }), ex);
                }
            });

            if(!tc.WaitExecute(TimeSpan.FromSeconds(100))){                
                //获取配置超时
                this.Shutdown();

                Log.E("system", "get_xml_timeout" + LogExtension.FormatDictory(
                        new Dictionary<string, string>() { { "url", url } }));

                return;
            }

            //对比目前版本号
            string verInConfig = cp.GetVal("version", "");
            if (string.Compare( verInConfig, GetCurrentVersion(), true) == 0) {
                //版本号一致，无需升级
                this.Shutdown();

                Log.I("system", "latest_already");

                return;
            }

            base.OnStartup(e);
        }

        protected override void OnExit(ExitEventArgs e)
        {
            if (m != null)
            {
                m.Dispose();
            }
            LogFlush();
            base.OnExit(e);
        }

        private string GetCurrentVersion() {
            if (!this.Properties.Contains("currentver")) {
                this.Properties["currentver"] = "1.0";
            }
            return this.Properties["currentver"].ToString();
        }

        public static IConfigParser Config {
            get {
                return Application.Current.Properties["cp"] as IConfigParser;
            }
        }

        public static string AppFolder {
            get {
                return Path.GetDirectoryName( Application.Current.GetType().Assembly.Location);
            }
        }

        public static IDictionary Cache {
            get {
                return Application.Current.Properties;
            }
        }

        private static void InitLog() {
            //实例化日志
            log = new FileLog();
            log.LoadConfig((new XmlConfigParser().Load(@" 
<root>
        <!-- 日志级别，如果是空字符串或all，就所有级别都记录；如果需要过滤，则Debug,Info,Warning,Error,Fatal，用逗号隔开 -->
        <val key=""level"">all</val>
        <!-- 记录日志的根目录文件夹，如果是web支持""~/xx""的格式，支持相对路径和绝对路径 -->
        <val key=""folder"">log</val>
        <!-- 日志文件格式，支持时间格式化，默认为yyyyMMdd.log -->
        <val key=""fileFormat"">""log_""yyyyMMdd"".log""</val>
        <!-- 日志缓冲写入条数，需要大于1 --> 
        <val key=""buffer"">10</val>
     </root>
")));
        }
    }
}
